package com.loong.member.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.loong.common.enumerate.ProductStatus;
import com.loong.common.enumerate.ResultCode;
import com.loong.common.exception.GlobalException;
import com.loong.common.rest.rpc.RPCResponse;
import com.loong.common.utils.TransformUtils;
import com.loong.data.dto.GoodsDTOResult;
import com.loong.data.dto.ShopDTOResult;
import com.loong.data.service.IGoodsService;
import com.loong.data.service.IShopService;
import com.loong.member.business.CartBusiness;
import com.loong.member.common.forehead.param.*;
import com.loong.member.common.forehead.result.CartAndCartItemForeheadResult;
import com.loong.member.common.forehead.result.CartItemForeheadResult;
import com.loong.member.common.forehead.result.CartForeheadResult;
import com.loong.member.mapper.CartMapper;
import com.loong.member.model.Cart;
import com.loong.member.model.CartItem;
import com.loong.shop.dto.GoodsSkuDTOResultInShop;
import com.loong.shop.service.IGoodsSkuService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: 处理购物车业务的handler
 * @Author: 刘群
 * @Date: 2020/10/23 17:22
 */
@Slf4j
@Component
public class CartHandler {

    @Resource
    private CartBusiness cartBusiness;

    @Resource
    private CartMapper cartMapper;

    @Resource
    private CartItemHandler itemHandler;

    @DubboReference
    private IGoodsService goodsService;

    @DubboReference
    private IShopService shopService;

    @DubboReference
    private IGoodsSkuService goodsSkuService;


    /**
     * RPC调用的方法：删除购物车及对应的购物详情
     *
     * @param cartId 购物车id
     */
    @Transactional
    public void rpcUpdatePaidCart(Long cartId) {
        //删除该购物车下的所有购物详情
        itemHandler.deleteCartItemByCartId(cartId);
        //删除购物车
        cartBusiness.deleteById(cartId);
    }

    /**
     * 前台根据用户id查询购物车集合
     *
     * @param userId 用户id
     * @return 购物车结果集合
     */
    public List<CartAndCartItemForeheadResult> foreheadQueryCartListByUserId(Long userId) {
        List<CartAndCartItemForeheadResult> totalResult = new ArrayList<>();
        //获取用户的购物车集合
        List<Cart> cartList = cartMapper.findCartListByUserId(userId);
        for (Cart cart : cartList) {
            //封装购物车的结果
            CartForeheadResult cartForeheadResult = TransformUtils.transform(cart, CartForeheadResult.class);
            CartAndCartItemForeheadResult result = this.foreheadPackingCartAndCartItemResult(cartForeheadResult);
            if (ObjectUtils.isNotEmpty(result)){
                totalResult.add(result);
            }
        }
        return totalResult;
    }

    /**
     * 前端根据用户id统计用户所有购物车中的商品数量
     * @param userId 用户id
     * @return 商品数量
     */
    public Integer foreheadCalculateGoodsNumInUserCarts(Long userId){
        Integer totalNum = 0;
        List<CartAndCartItemForeheadResult> resultList = this.foreheadQueryCartListByUserId(userId);
        for (CartAndCartItemForeheadResult result : resultList) {
            totalNum += result.getCartForeheadResult().getGoodsTotalNum();
        }
        return totalNum;
    }

    /**
     * 前台根据用户id和商家id查询购物车
     *
     * @param param 商家id和用户id封装的结果
     * @return 购物车结果
     */
    public CartAndCartItemForeheadResult foreheadQuerySingleCart(CartQueryForeheadParam param) {
        //查询参数封装
        CartForeheadParam cartForeheadParam = CartForeheadParam.builder()
                .userId(param.getUserId())
                .sellerId(param.getSellerId())
                .cartStatus(true).build();
        //根据用户id、商家id、购物车状态为true(未结算)，查询购物车
        List<Cart> cartList = cartBusiness.findCartByParam(cartForeheadParam);
        if (CollectionUtils.isEmpty(cartList)) return null;
        CartForeheadResult cartForeheadResult = TransformUtils.transform(cartList.get(0), CartForeheadResult.class);
        return this.foreheadPackingCartAndCartItemResult(cartForeheadResult);
    }

    /**
     * 抽取出的重复代码：封装购物车和购物详情的结果
     * @param cartForeheadResult 购物车
     * @return 购物车和购物详情封装的结果
     */
    private CartAndCartItemForeheadResult foreheadPackingCartAndCartItemResult(CartForeheadResult cartForeheadResult){
        //根据购物车中的商家id查询商家
        RPCResponse<ShopDTOResult> rpcResponse = shopService.findShopModelById(cartForeheadResult.getSellerId());
        ShopDTOResult shopDTOResult = rpcResponse.getData();
        if (ObjectUtils.isEmpty(shopDTOResult)) throw new GlobalException(ResultCode.DATA_ERROR,"没有查询到店铺");
        //添加商家名称到购物车结果中
        cartForeheadResult.setSellerName(shopDTOResult.getName());
        //添加商家图片到购物车结果中
        cartForeheadResult.setSellerPicture(shopDTOResult.getLogo());
        //添加商家纬度到购物车结果中
        cartForeheadResult.setSellerLatitude(shopDTOResult.getLatitude());
        //添加商家经度到购物车结果中
        cartForeheadResult.setSellerLongitude(shopDTOResult.getLongitude());
        //查询该购物车下所有的购物详情
        List<CartItemForeheadResult> itemResultList = itemHandler.findCartItemByCartId(cartForeheadResult.getId());
        //计算商品总数
        Integer goodsTotalNum = 0;
        if (CollectionUtils.isEmpty(itemResultList)) return null;
        for (CartItemForeheadResult cartItem : itemResultList) {
            goodsTotalNum += cartItem.getGoodsNum();
        }
        cartForeheadResult.setGoodsTotalNum(goodsTotalNum);
        //封装购物车和购物详情的结果集
        return CartAndCartItemForeheadResult.builder()
                .cartForeheadResult(cartForeheadResult)
                .itemResultList(itemResultList)
                .build();
    }

    /**
     * 前台删除单个购物车
     *
     * @param userId 用户id
     * @param cartId 购物车id
     */
    @Transactional
    public void foreheadDeleteCart(Long userId, Long cartId) {
        //删除该购物车下的所有购物详情
        itemHandler.deleteCartItemByCartId(cartId);
        //根据用户id和购物车id删除该购物车
        cartBusiness.deleteCartByCondition(userId, cartId);
    }

    /**
     * 前台删除购物车
     * @param param 购物车id集合
     */
    @Transactional
    public void foreheadDeleteCarts(CartDeleteForeheadParam param) {
        List<Long> idList = param.getCartIdList();
        for (Long cartId : idList) {
            this.foreheadDeleteCart(param.getUserId(), cartId);
        }
    }

    /**
     * 清空单个购物车
     * @param cartId 购物车id
     */
    @Transactional
    public void foreheadClearCart(Long cartId){
        //删除该购物车下的所有购物详情
        itemHandler.deleteCartItemByCartId(cartId);
        BigDecimal price = new BigDecimal(0);
        //更新购物车中的数据，价格都更新为0
        CartForeheadParam cartForeheadParam = CartForeheadParam.builder()
                .id(cartId)
                .discountPrice(price)
                .foodBoxFee(price)
                .payPrice(price)
                .totalPrice(price)
                .lastUpdateTime(new Date())
                .build();
        cartBusiness.updateByPrimaryKeySelective(TransformUtils.transform(cartForeheadParam,Cart.class));
    }

    /**
     * 前台新增购物车和购物详情
     *
     * @param param 购物车和购物详情集合封装的参数
     */
    @Transactional
    public void foreheadSaveCartAndCartItem(CartAndCartItemForeheadParam param) {
        CartForeheadParam cartForeheadParam = param.getCartParam();
        List<CartItemForeheadParam> itemParamList = param.getItemParamList();
        //根据用户id、商家id、购物车状态为true(未结算)，查询购物车
        List<Cart> cartList = cartBusiness.findCartByParam(cartForeheadParam);
        Cart cart = TransformUtils.transform(cartForeheadParam, Cart.class);
        if(CollectionUtils.isEmpty(cartList)){
            //用户在指定商家中不存在未结算的购物车，则直接新增
            cart.setId(null);
            cart.setCartStatus(true);
            cart.setCreateTime(new Date());
            //新增购物车
            cartBusiness.save(cart);
        }else {
            //用户在指定商家中存在未结算的购物车，则清空改购物车
            if (cartList.size() == 1){
                //清空购物车
                this.foreheadClearCart(cartList.get(0).getId());
                //获取清空之后的购物车
                cart = cartBusiness.findById(cartList.get(0).getId());
            }
        }
        //总价
        BigDecimal totalPrice = new BigDecimal(0);
        //总餐盒费
        BigDecimal totalBoxFee = new BigDecimal(0);
        if (CollectionUtils.isEmpty(itemParamList)){
            //如果购物详情集合参数为空，则直接删除数据库中该购物车下的所有购物详情
            itemHandler.deleteCartItemByCartId(cart.getId());
        }else {
            //新增购物详情
            String jsonStr = JSONArray.toJSONString(itemParamList);
            List<CartItem> cartItemList = JSON.parseArray(jsonStr).toJavaList(CartItem.class);
            for (CartItem cartItem : cartItemList) {
                //根据goodsSku的id查询Goods。
                RPCResponse<GoodsDTOResult> rpcResponse = goodsService.findGoodsBySkuId(cartItem.getGoodsSkuId());
                GoodsDTOResult goodsDTO = rpcResponse.getData();
                if (ObjectUtils.isEmpty(goodsDTO)) throw new GlobalException(ResultCode.DATA_ERROR, "没有查询到商品");
                //根据商品skuId查询商品sku
                RPCResponse<GoodsSkuDTOResultInShop> rpcResponseGoodsSku = goodsSkuService.findGoodsSkuBySkuId(cartItem.getGoodsSkuId());
                GoodsSkuDTOResultInShop goodSkuDTO = rpcResponseGoodsSku.getData();
                if (ObjectUtils.isEmpty(goodSkuDTO)) throw new GlobalException(ResultCode.DATA_ERROR, "没有查询到商品sku");
                //购物详情中商品数量
                BigDecimal goodsNum = new BigDecimal(cartItem.getGoodsNum());
                //计算详情总价:商品当前价*商品数量
                BigDecimal itemPrice = goodSkuDTO.getCurrentPrice().multiply(goodsNum);
                //计算购物车总价
                totalPrice = totalPrice.add(itemPrice);
                //计算购物详情中的餐盒费：商品餐盒费*商品数量
                BigDecimal singleBoxFee = goodsDTO.getPackingExpense();//单个商品的餐盒费
                BigDecimal itemBoxFee = singleBoxFee.multiply(goodsNum);
                //计算购物车中总餐盒费
                totalBoxFee = totalBoxFee.add(itemBoxFee);
                //封装购物车详情
                cartItem.setCartId(cart.getId());
                cartItem.setId(null);
                cartItem.setItemPrice(itemPrice);
                cartItem.setGoodsStatus(ProductStatus.ON_SELL.getCode());//商品状态为销售中
                cartItem.setCreateTime(new Date());
                //将购物详情添加到数据库中
                itemHandler.saveCartItem(cartItem);
            }
        }
        //TODO 这里暂时没考虑优惠的计算
        //实际应付的价格: 总价+餐盒费-优惠价
        BigDecimal payPrice = totalPrice.add(totalBoxFee);
        //封装更新购物车的参数
        CartForeheadParam updateCart = CartForeheadParam.builder()
                .id(cart.getId())
                .foodBoxFee(totalBoxFee)
                .totalPrice(totalPrice)
                .payPrice(payPrice)
                .discountPrice(new BigDecimal(0))
                .lastUpdateTime(new Date())
                .build();
        //更新购物车的价格等数据到数据库中
        cartBusiness.updateByPrimaryKeySelective(TransformUtils.transform(updateCart,Cart.class));
    }
}
